home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / answrbok / 6_6.lha / 6_6 / 6_6.h next >
C/C++ Source or Header  |  1993-08-08  |  5KB  |  327 lines

  1. * Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
  2. * The C++ Answer Book */
  3. * Tony Hansen */
  4. * All rights reserved. */
  5. / Exercise 6.6
  6. / String class with value semantics,
  7. / delayed copying on assignment, and
  8. / substring and contenation operators.
  9. ifndef STR_H
  10.  define STR_H
  11.  include <stream.h>
  12.  include <string.h>
  13.  
  14. / define the class to manage the
  15. / actual character string
  16. lass srep
  17.  
  18.    char *s;
  19.    int size;
  20.    int refcnt;
  21.  
  22.    friend class string;
  23.    friend class substring;
  24.  
  25.    srep()
  26.    {
  27. refcnt = 1;
  28. s = new char[size = 1];
  29. s[0] = 0;
  30.    }
  31.  
  32.    srep(int sz)
  33.    {
  34. refcnt = 1;
  35. s = new char[size = sz];
  36. s[0] = 0;
  37.    }
  38.  
  39.    srep(char *x)
  40.    {
  41. refcnt = 1;
  42. s = new char[size = strlen(x) + 1];
  43. strcpy(s, x);
  44.    }
  45.  
  46.    srep(char *x, int len)
  47.    {
  48. refcnt = 1;
  49. s = new char[size = len + 1];
  50. strncpy(s, x, len);
  51.    }
  52.  
  53.    srep& operator=(srep &x)
  54.    {
  55. delete s;
  56. refcnt = 1;
  57. s = new char[size = x.size];
  58. strcpy(s, x.s);
  59. return *this;
  60.    }
  61.  
  62.    srep& operator=(char *x)
  63.    {
  64. delete s;
  65. refcnt = 1;
  66. s = new char[size = strlen(x) + 1];
  67. strcpy(s, x);
  68. return *this;
  69.    }
  70.  
  71.    // Reallocate the char space, copying
  72.    // in the specified string. Delay deleting
  73.    // the old string in case the string to
  74.    // copy is from there.
  75.    void realloc(char *ns, int nlen)
  76.    {
  77. char *olds = s;
  78. s = new char[size = nlen];
  79. strcpy(s, ns);
  80. delete olds;
  81.    }
  82.  
  83.    ~srep()
  84.    { delete s; }
  85. ;
  86.  
  87. / a helper typedef for the cast
  88. / back into a character pointer
  89. ypedef const char *charptr;
  90.  
  91. lass string
  92.  
  93.    srep *p;
  94.    friend class string_iterator;
  95.    friend class substring;
  96.  
  97.    char *str()
  98.    { return p->s; }
  99.  
  100.    int len()
  101.    { return p->size; }
  102.    int refcnt()        // DELETE
  103.    { return p->refcnt; }    // DELETE
  104.  
  105. ublic:
  106.    // string s;
  107.    string()
  108.    { p = new srep; }
  109.  
  110.    // string s(5);
  111.    string(int sz)
  112.    { p = new srep(sz); }
  113.  
  114.    // string s("xyz");
  115.    string(char *s)
  116.    { p = new srep(s); }
  117.  
  118.    // string s(string)
  119.    string(string &s)
  120.    { s.p->refcnt++; p = s.p; }
  121.  
  122.    // string(substring)
  123.    string(substring&);
  124.  
  125.    ~string()
  126.    {
  127. if (--p->refcnt == 0)
  128.     delete p;
  129.    }
  130.  
  131.    // s = string
  132.    string& operator=(string &s)
  133.    {
  134. s.p->refcnt++;
  135. if (--p->refcnt == 0)
  136.     delete p;
  137. p = s.p;
  138. return *this;
  139.    }
  140.  
  141.    // s = "xyz";
  142.    string& operator=(char *s)
  143.    {
  144. if (p->refcnt > 1)
  145.     {
  146.     p->refcnt--;
  147.     p = new srep(s);
  148.     }
  149.  
  150. else
  151.     p->realloc(s, strlen(s) + 1);
  152. return *this;
  153.    }
  154.  
  155.    // s = substring;
  156.    string& operator=(substring&);
  157.  
  158.    // const char *c = s;
  159.    charptr operator charptr()
  160.    {
  161. return (charptr) str();
  162.    }
  163.  
  164.    // substring x = s(3,5);
  165.    substring operator()(int i, int len = -1);
  166.  
  167.    // x = s[3];
  168.    // s[3] = 'x';
  169.    char &operator[](int i)
  170.    {
  171. if (i < 0 || i >= len())
  172.     return str()[0];
  173.  
  174. else
  175.     return str()[i];
  176.    }
  177.  
  178.    // concatenation
  179.    // str = str1 + str2;
  180.    friend string operator+(string &s1, string &s2)
  181.    {
  182. string ret(s1.len() + s2.len() - 1);
  183. strcpy(ret.str(), s1.str());
  184. strcat(ret.str(), s2.str());
  185. return ret;
  186.    }
  187.  
  188.    // append to end
  189.    // str1 += str2;
  190.    string &operator+=(string &s)
  191.    {
  192. int nlen = len() + s.len();
  193.  
  194. // have to disconnect from
  195. // the old string
  196. if (p->refcnt > 1)
  197.     {
  198.     p->refcnt--;
  199.     srep *oldp = p;
  200.     p = new srep(oldp->s, nlen);
  201.     strcat(str(), s.str());
  202.     }
  203.  
  204. // we can reallocate the
  205. // current string area
  206. else
  207.     {
  208.     p->realloc(p->s, nlen);
  209.     strcat(str(), s.str());
  210.     }
  211.  
  212. return *this;
  213.    }
  214.  
  215.    friend ostream& operator<<(ostream&, string&);
  216.    friend istream& operator>>(istream&, string&);
  217.  
  218. define defop(op)                    \
  219.    friend int operator op(string &x, char *s)        \
  220.    { return strcmp(x.str(), s) op 0; }            \
  221.    friend int operator op(string &x, string &y)    \
  222.    { return strcmp(x.str(), y.str()) op 0; }
  223.  
  224.    defop(==); defop(!=);
  225.    defop(<); defop(<=);
  226.    defop(>); defop(>=);
  227.    undef defop
  228. ;
  229.  
  230. lass string_iterator
  231.  
  232.    char *cp;
  233.  
  234. ublic:
  235.    string_iterator(string &s)
  236.    { cp = s.str(); }
  237.  
  238.    char& operator()()
  239.    { char *r = cp++; return *r; }
  240. ;
  241.  
  242. lass substring
  243.  
  244.    friend class string;
  245.  
  246.    char *s;        // ptr to substring start
  247.    int len;        // length of substring
  248.    string *str;    // ptr to parent string
  249.  
  250.    substring(char *chptr, int stlen, string *stptr)
  251.    {
  252. s = chptr;
  253. len = stlen;
  254. str = stptr;
  255.    }
  256.  
  257. ublic:
  258.    // substring x = ...
  259.    substring(substring &sst)
  260.    {
  261. s = sst.s;
  262. len = sst.len;
  263. str = sst.str;
  264.    }
  265.  
  266.    substring &operator=(substring&);
  267.    substring &operator=(string&);
  268.    substring &operator=(char*);
  269.  
  270.    // cout << substring
  271.    friend ostream &operator<<(ostream&, substring&);
  272. ;
  273.  
  274. / cout << string
  275. nline ostream &operator<<(ostream &s, string &x)
  276.  
  277. ifdef NOTDEF            // DELETE
  278.    return s << x.str();
  279. else                // DELETE
  280.    return s << x.str() <<    // DELETE
  281. "[len=" << x.len() << ",ref=" << x.refcnt() << "]";    // DELETE
  282. endif                // DELETE
  283.  
  284.  
  285. / cout << substring
  286. nline ostream &operator<<(ostream &out, substring &sst)
  287.  
  288.    string st(sst);
  289.    return out << st;
  290.  
  291.  
  292. / cin >> string
  293. nline istream& operator>>(istream &s, string &x)
  294.  
  295.    char buf[1024];
  296.    s >> buf;
  297.    x = buf;
  298.    return s;
  299.  
  300.  
  301. / s = substring;
  302. nline string& string::operator=(substring &sst)
  303.  
  304.    string st(sst);
  305.    return *this = st;
  306.  
  307.  
  308. / string(substring)
  309. tring::string(substring &sst)
  310.  
  311.    p = new srep(sst.s, sst.len);
  312.  
  313.  
  314. / substring = string
  315. nline substring &substring::operator=(string &st)
  316.  
  317.    return *this = st.str();
  318.  
  319.  
  320. / substring = substring
  321. nline substring &substring::operator=(substring &sst)
  322.  
  323.    string st(sst);
  324.    return *this = st;
  325.  
  326. endif /* STR_H */
  327.